package com.panopset.sf;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;

import com.panopset.Alert;
import com.panopset.io.FileProps;
import com.panopset.sf.FontManager.Size;
import com.panopset.sf.menu.SwingMenuBar;

/**
 * Application document file.
 * 
 * @author Karl Dinwiddie
 * 
 */
public class Windoc {
	
	public final ComponentFactory cf = new ComponentFactory();

	/**
	 * Properties.
	 */
	private FileProps fp;

	public FileProps getFileProps() {
		if (fp == null) {
			fp = new FileProps(sf.getAppBase().getNewFileFromUser(getFrame()));
		}
		return fp;
	}

	/**
	 * Parent.
	 */
	public final SwingFrame sf;

	public Windoc(final SwingFrame swingFrame, final File file) {
		sf = swingFrame;
		setFile(file);
	}

	private void setFile(final File file) {
		if (fp == null) {
			fp = new FileProps(file);
		} else {
			getFileProps().setFile(file);
		}
		getFrame().setTitle(
				this.sf.getClass().getSimpleName() + " - " + file.getName());
	}

	/**
	 * Open document.
	 */
	public void open() {
		File f = sf.getAppBase().getNewFileFromUser(getFrame());
		if (f != null && f.exists()) {
			sf.add(new Windoc(sf, f));
		}
	}

	public void close() {
		save();
		if (getFrame().isVisible()) {
			getFrame().setVisible(false);
			getFrame().dispose();
		}
		closed = true;
	}

	public void closeCheckForExit() {
		close();
		if (sf.getNumberOfOpenDocs() < 1) {
			sf.shutdownApplication();
		}
	}

	private boolean closed = false;

	protected boolean isClosed() {
		return closed;
	}

	/**
	 * Frame.
	 */
	private JFrame frm;

	public JFrame getFrame() {
		if (frm == null) {
			frm = new JFrame();		
			frm.setJMenuBar(getSwingMenu().getMenuBar());
			setFile(getFileProps().getFile());
			frm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			frm.setIconImage(sf.getIcon16x16());
			frm.add(createPanel(frm));
			frm.addWindowListener(new WindowAdapter() {

				@Override
				public void windowClosed(final WindowEvent e) {
					Windoc.this.closeCheckForExit();
				}
			});
			updateFontMenuCheckboxes(FontManager.getInstance().getSize());
			for (WindocField pf : pfs) {
				pf.load();
			}
		}
		return frm;
	}

	public static final String SD_MSG_PROPS = "com/panopset/nls/msg";

	public void save() {
		new FrameState(getFileProps()).save(getFrame(), getFileProps());
		for (WindocField pf : pfs) {
			pf.save();
		}
		getFileProps().flush();
	}

	public void saveas() {
		File f = sf.getAppBase().getNewFileFromUser(getFrame());
		if (f == null) {
			return;
		}
		setFile(f);
	}

	public void setToDefaults() {
		for (WindocField pf : pfs) {
			pf.setToDefaults();
		}
		new FrameState(getFileProps()).setToDefaults(getFrame());
	}

	public void doOpen() {
		File f = sf.getAppBase().getOpenedFileFromUser(getFrame());
		if (f == null) {
			return;
		}
		sf.add(new Windoc(sf, f));
	}

	private SwingMenuBar sm;

	public SwingMenuBar getSwingMenu() {
		if (sm == null) {
			sm = new SwingMenuBar(this);
		}
		return sm;
	}

	public void dspmsg(String msg) {
		Alert.green(msg);
	}

	public void dspwrn(String msg) {
		Alert.yellow(msg);
	}

	public void dsperr(String msg) {
		Alert.red(msg);
	}
	
	private JComponent createPanel(JFrame f) {
		JComponent p = sf.createPanel(this);
		new FrameState(getFileProps()).update(f);
		return p;
	}

	public void show() {
		getFrame().setVisible(true);
	}

	/**
	 * Set the correct checkbox state of the font menu items.
	 * 
	 * @param size
	 *            Font.Size to set.
	 */
	public void updateFontMenuCheckboxes(final Size size) {
		for (int i = 0; i < getSwingMenu().getFontMenu().getMenu()
				.getItemCount(); i++) {
			JMenuItem mi = getSwingMenu().getFontMenu().getMenu().getItem(i);
			mi.setSelected(mi.getText().equals(size.name()));
		}
	}

	public PanTextField createPanTextField(final String title,
			final String defaultValue) {
		return new PanTextField(this, title, defaultValue);
	}

	public PanFile createPanFile(final String title, final String defaultPath) {
		return new PanFile(this, title, defaultPath);
	}

	public static JButton createPanButton(String title,
			MnemonicGroup mnemonicGroup) {
		JButton rtn = new JButton(title);
		rtn.setMnemonic(mnemonicGroup.findMnemonic(rtn));
		FontManager.getInstance().register(rtn, FontManager.FontType.boldArial);
		return rtn;
	}
	
	private List<WindocField> pfs = new ArrayList<WindocField>();

	public PanVal register(WindocField pf, String defaultValue, String keyValue) {
		PanVal panVal = new PanVal(new Pan() {

			@Override
			public String get(String key) {
				return getFileProps().get(key);
			}

			@Override
			public void put(String key, String value) {
				getFileProps().put(key, value);
			}
			
		});
		panVal.setDefault(defaultValue);
		pfs.add(pf);
		return panVal;
	}
	
	public PanVal register(WindocField pf, String defaultValue) {
		return register(pf, defaultValue, null);
	}
}
